package com.yunchao.library.socket.model.error

import com.yunchao.library.socket.constants.Errors
import com.yunchao.library.socket.constants.Limits
import com.yunchao.library.socket.extensions.getString
import com.yunchao.library.socket.extensions.toReadOnlyBuffer
import com.yunchao.library.socket.utils.ValidationUtils

data class ErrorFeedback(
    val level: Level,
    val message: String,
    val branch: Int = 0,
    val details: String = ""
) {
    enum class Level(val value: Int) {
        INFO(0x00), WARN(0x01), ERROR(0x02), FATAL(0xFF);

        companion object {
            fun fromValue(value: Int): Level = Level.entries.firstOrNull { it.value == value }
                ?: throw IllegalArgumentException("${Errors.INVALID_LEVEL}: 0x${value.toString(16)}")
        }
    }

    init {
        ValidationUtils.validateString(message, "Message")
        ValidationUtils.validateString(details, "Details", Limits.MAX_DETAILS_LENGTH)
    }

    companion object {
        fun fromByteArray(bytes: ByteArray): ErrorFeedback {
            val buffer = bytes.toReadOnlyBuffer()
            return ErrorFeedback(
                level = Level.fromValue(buffer.get().toInt() and 0xFF),
                message = buffer.getString(),
                branch = buffer.int,
                details = if (buffer.remaining() >= 4) buffer.getString() else ""
            )
        }

        fun info(message: String) = ErrorFeedback(Level.INFO, message)
        fun warn(message: String) = ErrorFeedback(Level.WARN, message)
        fun error(message: String) = ErrorFeedback(Level.ERROR, message)
        fun fatal(message: String) = ErrorFeedback(Level.FATAL, message)
    }
}